import { IImportExportService } from './interfaces/IImportExportService';
import { LLMConfig, ExportedConfig, ImportResult } from '../types/index';

export class ImportExportService implements IImportExportService {
  private readonly CONFIG_VERSION = '1.0.0';
  private readonly MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB

  async exportConfig(): Promise<void> {
    try {
      // 从Chrome存储获取当前配置
      const result = await new Promise<{ llmConfig?: LLMConfig }>((resolve) => {
        chrome.storage.sync.get(['llmConfig'], resolve);
      });

      if (!result.llmConfig) {
        throw new Error('没有找到配置信息');
      }

      // 生成导出数据
      const exportData = this.generateExportData(result.llmConfig);
      
      // 创建并下载文件
      await this.downloadFile(exportData);
    } catch (error) {
      console.error('导出配置失败:', error);
      throw new Error(`导出配置失败: ${error instanceof Error ? error.message : '未知错误'}`);
    }
  }

  async importConfig(file: File, mergeMode = false): Promise<ImportResult> {
    // 文件大小检查
    if (file.size > this.MAX_FILE_SIZE) {
      return {
        success: false,
        importedKeys: [],
        skippedKeys: [],
        errors: ['文件大小超过限制（10MB）']
      };
    }

    // 文件类型检查
    if (!file.name.endsWith('.json') && file.type !== 'application/json') {
      return {
        success: false,
        importedKeys: [],
        skippedKeys: [],
        errors: ['文件格式不正确，请选择JSON文件']
      };
    }

    try {
      // 读取文件内容
      const content = await this.readFileContent(file);
      
      // 验证文件格式
      const validation = this.validateConfigFile(content);
      if (!validation.isValid) {
        return {
          success: false,
          importedKeys: [],
          skippedKeys: [],
          errors: [validation.error || '文件格式验证失败']
        };
      }

      const importedConfig = validation.data!.config;

      // 获取现有配置
      const existingResult = await new Promise<{ llmConfig?: LLMConfig }>((resolve) => {
        chrome.storage.sync.get(['llmConfig'], resolve);
      });

      let finalConfig: LLMConfig;
      const importedKeys: string[] = [];
      const skippedKeys: string[] = [];

      if (mergeMode && existingResult.llmConfig) {
        // 合并模式
        finalConfig = this.mergeConfigs(existingResult.llmConfig, importedConfig);
        
        // 记录导入的键
        Object.keys(importedConfig).forEach(key => {
          if (JSON.stringify(importedConfig[key as keyof LLMConfig]) !== 
              JSON.stringify(existingResult.llmConfig![key as keyof LLMConfig])) {
            importedKeys.push(key);
          } else {
            skippedKeys.push(key);
          }
        });
      } else {
        // 覆盖模式
        finalConfig = importedConfig;
        importedKeys.push(...Object.keys(importedConfig));
      }

      // 保存配置
      await new Promise<void>((resolve, reject) => {
        chrome.storage.sync.set({ llmConfig: finalConfig }, () => {
          if (chrome.runtime.lastError) {
            reject(new Error(chrome.runtime.lastError.message));
          } else {
            resolve();
          }
        });
      });

      return {
        success: true,
        importedKeys,
        skippedKeys
      };
    } catch (error) {
      console.error('导入配置失败:', error);
      return {
        success: false,
        importedKeys: [],
        skippedKeys: [],
        errors: [error instanceof Error ? error.message : '导入过程中发生未知错误']
      };
    }
  }

  validateConfigFile(content: string): {
    isValid: boolean;
    error?: string;
    data?: ExportedConfig;
  } {
    try {
      const data = JSON.parse(content);

      // 检查基本结构
      if (!data || typeof data !== 'object') {
        return { isValid: false, error: '文件内容不是有效的JSON对象' };
      }

      // 检查版本
      if (!data.version || typeof data.version !== 'string') {
        return { isValid: false, error: '文件缺少版本信息' };
      }

      // 检查配置对象
      if (!data.config || typeof data.config !== 'object') {
        return { isValid: false, error: '文件缺少配置信息' };
      }

      const config = data.config;

      // 验证必需字段
      const requiredFields = ['llm', 'apiKey', 'modelName', 'options'];
      for (const field of requiredFields) {
        if (!(field in config)) {
          return { isValid: false, error: `配置缺少必需字段: ${field}` };
        }
      }

      // 验证字段类型
      if (typeof config.llm !== 'string') {
        return { isValid: false, error: 'llm字段必须是字符串' };
      }

      if (typeof config.apiKey !== 'string') {
        return { isValid: false, error: 'apiKey字段必须是字符串' };
      }

      if (typeof config.modelName !== 'string') {
        return { isValid: false, error: 'modelName字段必须是字符串' };
      }

      if (!config.options || typeof config.options !== 'object') {
        return { isValid: false, error: 'options字段必须是对象' };
      }

      if (typeof config.options.baseURL !== 'string') {
        return { isValid: false, error: 'options.baseURL字段必须是字符串' };
      }

      // 验证供应商
      const validProviders = ['openai', 'anthropic', 'openrouter', 'openai-compatible'];
      if (!validProviders.includes(config.llm)) {
        return { isValid: false, error: `不支持的LLM供应商: ${config.llm}` };
      }

      return { isValid: true, data };
    } catch (error) {
      return { 
        isValid: false, 
        error: `JSON解析失败: ${error instanceof Error ? error.message : '未知错误'}` 
      };
    }
  }

  mergeConfigs(existing: LLMConfig, imported: LLMConfig): LLMConfig {
    return {
      llm: imported.llm || existing.llm,
      apiKey: imported.apiKey || existing.apiKey,
      modelName: imported.modelName || existing.modelName,
      options: {
        ...existing.options,
        ...imported.options,
        baseURL: imported.options.baseURL || existing.options.baseURL
      }
    };
  }

  generateExportData(config: LLMConfig): ExportedConfig {
    return {
      version: this.CONFIG_VERSION,
      exportDate: new Date().toISOString(),
      config: {
        llm: config.llm,
        apiKey: config.apiKey,
        modelName: config.modelName,
        options: { ...config.options }
      },
      metadata: {
        userAgent: navigator.userAgent,
        extensionVersion: chrome.runtime.getManifest().version,
        configHash: this.generateConfigHash(config)
      }
    };
  }

  /**
   * 生成配置快速验证用的预览信息
   */
  generateConfigPreview(content: string): {
    isValid: boolean;
    preview?: {
      provider: string;
      modelName: string;
      baseURL: string;
      exportDate?: string;
      version?: string;
    };
    error?: string;
  } {
    const validation = this.validateConfigFile(content);
    if (!validation.isValid) {
      return { isValid: false, error: validation.error };
    }

    const data = validation.data!;
    return {
      isValid: true,
      preview: {
        provider: data.config.llm,
        modelName: data.config.modelName,
        baseURL: data.config.options.baseURL,
        exportDate: data.exportDate,
        version: data.version
      }
    };
  }

  private async readFileContent(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = () => reject(new Error('文件读取失败'));
      reader.readAsText(file, 'utf-8');
    });
  }

  private async downloadFile(exportData: ExportedConfig): Promise<void> {
    const jsonContent = JSON.stringify(exportData, null, 2);
    const blob = new Blob([jsonContent], { type: 'application/json' });
    const url = URL.createObjectURL(blob);

    const filename = `eko-extension-config-${new Date().toISOString().split('T')[0]}.json`;

    // 使用Chrome下载API
    if (chrome.downloads) {
      chrome.downloads.download({
        url: url,
        filename: filename,
        saveAs: true
      }, (downloadId) => {
        URL.revokeObjectURL(url);
        if (chrome.runtime.lastError) {
          throw new Error(chrome.runtime.lastError.message);
        }
      });
    } else {
      // 备用方案：创建下载链接
      const link = document.createElement('a');
      link.href = url;
      link.download = filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    }
  }

  private generateConfigHash(config: LLMConfig): string {
    // 简单的配置哈希生成（实际应用中可能需要更复杂的算法）
    const configString = JSON.stringify({
      llm: config.llm,
      modelName: config.modelName,
      baseURL: config.options.baseURL
    });
    
    // 简单哈希算法
    let hash = 0;
    for (let i = 0; i < configString.length; i++) {
      const char = configString.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash; // 转换为32位整数
    }
    
    return Math.abs(hash).toString(16);
  }
}